/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ntweets.services;

import entities.Status;
import java.util.ArrayList;
import net.oauth.OAuth.Parameter;
import net.oauth.OAuthAccessor;
import net.oauth.OAuthMessage;
import net.oauth.client.OAuthClient;
import net.oauth.client.httpclient4.HttpClient4;
import net.oauth.http.HttpClient;
import ntweets.NTweetException;
import org.json.JSONArray;
import org.json.JSONObject;
import utilities.Key;

/**
 *
 * @author olawale
 */
public class ServiceCall {

    private ServiceCall(){
        accessor = InitAccessor.getAccessor();
        http = new HttpClient4();
        client = new OAuthClient(http);
    }

    private static ServiceCall service;

    private OAuthAccessor accessor;
    private HttpClient http;
    private OAuthClient client;

    private static String format = ".json";
    private static String GET = "GET";
    private static String POST = "POST";
    private static String statusURL = "http://twitter.com/statuses/";
    private static String userURL = "http://twitter.com/users/";

    public static ServiceCall getService(){
        if(service == null)
            service = new ServiceCall();
        return service;
    }

    public Status showStatus(long id) throws NTweetException{
        try {
            String url = statusURL + "show/" + id + format;
            OAuthMessage result = client.invoke(accessor, GET, url, null);
            return new Status(result.readBodyAsString());
        } catch (Exception ex) {
            throw new NTweetException(ex);
        }
    }

    public Status updateStatus(ArrayList<Parameter> parameters) throws NTweetException{
        String url = statusURL + "update" + format;
        try {
            OAuthMessage result = client.invoke(accessor, POST, url, parameters);
            return new Status(result.readBodyAsString());
        } catch (Exception ex) {
            throw new NTweetException(ex);
        }
    }

    public Status destroy(long id) throws NTweetException{
        String url = statusURL + "destroy/" + id + format;
        try {
            OAuthMessage result =  client.invoke(accessor, POST, url, null);
            return new Status(result.readBodyAsString());
        } catch (Exception ex) {
            throw new NTweetException(ex);
        }
    }

    public OAuthMessage retweet(long id) throws Exception{
//        String url = statusURL + "retweet/" + id + format;
        throw new Exception("Not yet implemented");
    }

    public OAuthMessage retweets(long id) throws Exception{
//        String url = statusURL + "retweets/" + id + format;
        throw new Exception("Not yet implemented");
    }

    public ArrayList<Status> publicTimeline() throws NTweetException{
        try {
            String url = statusURL + "public_timeline/" + format;
            OAuthMessage result =  client.invoke(accessor, GET, url, null);
            JSONObject json = new JSONObject(result.readBodyAsString());
            JSONArray statuses = json.getJSONArray(Key.status);
            ArrayList<Status> allStatus = new ArrayList();
            for(int i = 0; i < statuses.length(); i++){
                allStatus.add(new Status(statuses.getString(i)));
            }
            return allStatus;
        } catch (Exception ex) {
            throw new NTweetException(ex);
        }
    }

    public ArrayList<Status> homeTimeline(ArrayList<Parameter> parameters) throws NTweetException{
        try {
            String url = statusURL + "home_timeline/" + format;
            OAuthMessage result = client.invoke(accessor, GET, url, parameters);
            JSONObject json = new JSONObject(result.readBodyAsString());
            JSONArray statuses = json.getJSONArray(Key.status);
            ArrayList<Status> allStatus = new ArrayList();
            for(int i = 0; i < statuses.length(); i++){
                allStatus.add(new Status(statuses.getString(i)));
            }
            return allStatus;
        } catch (Exception ex) {
            throw new NTweetException(ex);
        }
    }

    public ArrayList<Status> friendsTimeline(ArrayList<Parameter> parameters) throws NTweetException{
        try {
            String url = statusURL + "friends_timeline/" + format;
            OAuthMessage result = client.invoke(accessor, GET, url, parameters);
            JSONObject json = new JSONObject(result.readBodyAsString());
            JSONArray statuses = json.getJSONArray(Key.status);
            ArrayList<Status> allStatus = new ArrayList();
            for(int i = 0; i < statuses.length(); i++){
                allStatus.add(new Status(statuses.getString(i)));
            }
            return allStatus;
        } catch (Exception ex) {
            throw new NTweetException(ex);
        }
    }

    public ArrayList<Status> userTimeline(ArrayList<Parameter> parameters) throws NTweetException{
        try {
            String url = statusURL + "user_timeline/" + format;
            OAuthMessage result = client.invoke(accessor, GET, url, parameters);
            JSONObject json = new JSONObject(result.readBodyAsString());
            JSONArray statuses = json.getJSONArray(Key.status);
            ArrayList<Status> allStatus = new ArrayList();
            for(int i = 0; i < statuses.length(); i++){
                allStatus.add(new Status(statuses.getString(i)));
            }
            return allStatus;
        } catch (Exception ex) {
            throw new NTweetException(ex);
        }
    }

    public OAuthMessage showUser(ArrayList<Parameter> parameters) throws Exception{
        String url = userURL + "show" + format;
        return client.invoke(accessor, GET, url, parameters);
    }

    public OAuthMessage friends(ArrayList<Parameter> parameters) throws Exception{
        String url = statusURL + "friends" + format;
        return client.invoke(accessor, GET, url, parameters);
    }

    public OAuthMessage followers(ArrayList<Parameter> parameters) throws Exception{
        String url = statusURL + "followers" + format;
        return client.invoke(accessor, GET, url, parameters);
    }

}
